"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 故障&可靠性测试
Case Name   : DN主数据文件目录权限修改
Create At   : 2020/12/07
@zou_jialiang0505328126
Description :
    1、主节点执行tpcc，执行过程中进入主节点主数据目录，修改文件所属为root
    2、查看主/备节点状态；
    3、备节点连接数据库，功能正常
    4、改回dn1目录文件属组
    5、重启集群
    6、重启成功，查询主备数据一致性
Expect      :
    1、修改权限成功，tpcc运行中断
    2、主数据库状态：stop；备数据库状态：Need repair(Disconnected)
    3、备库可以查询操作
    4、修改权限成功
    5、重启成功，主备状态normal
    6、查询主备数据一致
History     :
    modified：2021-3-10 by 5328113;修改tpcc断言及脚本优化
    modified：2022-2-18 by @wan005:增加集群状态查询，方便定位问题
"""

import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Chowndn1(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info(
            '----Opengauss_Reliability_Dbsys_Case040.py 开始执行----')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_root = Node(node='PrimaryRoot')
        self.sta1_dbuser = Node(node='Standby1DbUser')
        self.sta2_dbuser = Node(node='Standby2DbUser')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.sta_1_sh = CommonSH('Standby1DbUser')
        self.sta_2_sh = CommonSH('Standby2DbUser')
        self.Constant = Constant()
        self.common = Common('PrimaryRoot')

    def test_basebackup(self):
        self.log.info('----1、主节点执行tpcc，执行过程中进入主节点主数据目录，修改文件所属为root----')
        self.log.info('============启动TPCC=================')
        tpcc_thread = ComThread(self.common.startTPCC,
                                args=(self.pri_root, macro.TPCC_PATH,))
        tpcc_thread.setDaemon(True)
        tpcc_thread.start()

        self.log.info('===========修改dn1属组================')
        time.sleep(2)
        shell_cmd = f"chown root:root {macro.DB_INSTANCE_PATH}"
        self.log.info(shell_cmd)
        result = self.pri_root.sh(shell_cmd).result()
        self.log.info(result)

        self.log.info('===============检查TPCC结果===============')
        tpcc_thread.join(60 * 60)
        result = tpcc_thread.get_result()
        self.log.info(result)
        error_flags = ('error', 'ERROR', 'FATAL')
        if self.Constant.TPCC_SUCCESS_MSG in result:
            self.assertTrue(any(error in result for error in error_flags))
        else:
            self.assertNotIn(self.Constant.TPCC_SUCCESS_MSG, result)

        self.log.info('----3、备节点连接数据库，功能正常----')
        result = self.sta_1_sh.executDbSql(r'\d')
        self.log.info(result)
        self.assertNotIn(self.Constant.FAILED_CONNECT_DB, result)

        self.log.info("----4、改回dn1目录文件属组----")
        shell_cmd = f"chown {self.pri_dbuser.ssh_user}:" \
            f"{self.pri_dbuser.ssh_user} {macro.DB_INSTANCE_PATH}"
        self.log.info(shell_cmd)
        result = self.pri_root.sh(shell_cmd).result()
        self.log.info(result)

        self.log.info("----5、重启集群----")
        result = self.pri_sh.stopDbCluster()
        self.assertTrue(result)
        result = self.pri_sh.startDbCluster()
        self.assertTrue(result)

        self.log.info('----6、重启成功，查询主备数据一致性----')
        result = self.sta_1_sh.check_data_consistency()
        self.assertTrue(result)
        result = self.sta_2_sh.check_data_consistency()
        self.assertTrue(result)

        self.log.info('----检查数据一致性----')
        nodes_tuple = (self.pri_dbuser, self.sta1_dbuser, self.sta2_dbuser)
        flag = self.common.check_data_sample_by_all(r'\d', *nodes_tuple)
        self.assertTrue(flag)

        table_dict = self.common.format_sql_result(
            self.pri_sh.executDbSql(r'\d'))
        table_name = table_dict.get('Name')
        for name in table_name:
            result = self.sta_1_sh.getDbClusterStatus('detail')
            self.log.info(result)
            select_sql = f'select count(*) from {name};'
            flag = self.common.check_data_sample_by_all(select_sql,
                                                        *nodes_tuple)
            self.assertTrue(flag)

    def tearDown(self):
        self.log.info('----环境清理----')
        self.log.info("----恢复dn1目录文件属组----")
        shell_cmd = f"chown {self.pri_dbuser.ssh_user}:" \
            f"{self.pri_dbuser.ssh_user} {macro.DB_INSTANCE_PATH}"
        self.log.info(shell_cmd)
        result = self.pri_root.sh(shell_cmd).result()
        self.log.info(result)

        self.log.info(
            '----Opengauss_Reliability_Dbsys_Case040.py 执行结束----')
